/**
 *@file matrix.h
 *@author Linghui
 *@date Thu 2021 Oct 7 8:56pm
 *@brief a headfile of main.cpp
 */


#ifndef __matrix__
#define __matrix__

#include <iostream>
#include <stdio.h>
using namespace std;

template <typename T>
class Matrix
{
protected:
  int n_row;
  int n_col;
  T** matrix_elements = NULL;

private:
    int n;

public:
    Matrix(int r = 0, int c = 0) :n_row(r), n_col(c) {};
    ~Matrix();
    Matrix operator*(Matrix &R);
    void get(int, int);//get the element of matrix.
    bool is_square()const;
    bool can_multiply(const Matrix &R);
    void show_matrix()const;//output the matrix

};

template <typename T>
void Matrix<T>::get(int r, int c)
{
    n_row = r;
    n_col = c;
    matrix_elements = new int* [r];
    for (int i = 0; i < n_row; i++)
    {
        matrix_elements[i] = new int[n_col];
    }
    for (int i = 0; i < n_row; i++)
    {
        for (int j = 0; j < n_col; j++)
        {
            cin >> matrix_elements[i][j];
        }
    }
}

template <typename T>
Matrix<T>::~Matrix()
{
    for (int i = 0; i < n_row; i++)
    {
        delete[] matrix_elements[i];
    }
    delete matrix_elements;
}

template <typename T>
bool Matrix<T>::is_square()const
{
    if (n_row == n_col)
    {
        return true;
    }
    else
    {
        return false;
    }
}

template <typename T>
bool Matrix<T>::can_multiply(const Matrix<T> &R)
{
  if (n_col == R.n_row)
  {
    return true;
  }
  else
  {
    return false;
  }
  }

template <typename T>
Matrix<T> Matrix<T>::operator*(Matrix<T> &R)
{
  Matrix c(n_row,R.n_col);
  c.matrix_elements=new int[n_row];
  for (int i=0;i<n_row;i++)
  {
    c.matrix_elements=new int[R.n_col];
  }
  for(int i=0;i<n_row;i++)
  {
    for(int j=0;j<n_col;j++)
    {
      for(int k=0;k<n_row;k++)
	{
	  c.matrix_elements[i][j]+=matrix_elements[i][k]*R.matrix_elements[k][j];
	}
    }
  }
  return c;
}

template <typename T>
void Matrix<T>::show_matrix() const
{
    for (int i = 0; i < n_row; i++)
    {
        for (int j = 0; j < n_col; j++)
        {
            cout << matrix_elements[i][j] << '\t';
        }
        cout << endl;
    }
}
/*a derivedclass but is have something wrong >.<
template <typename T>
class RowVector: public Matrix<T>
{
 private:
  T* rowvec = NULL;

 public:

  RowVector()
  {
    int i,j;
    for (int i = 0; i < n_row; i++)
    {
      for (int j = 0; j < n_col; j++)
      {
        rowvec[i]=matrix_elements[i][j]
      }
    }
  }
};

template <typename T>
class ColVector: public Matrix<T>
{
 private:
  T* colvec;

 public:

  ColVector()
  {
    int i,j;
    for (int i = 0; i < n_col; i++)
    {
      for (int j = 0; j < n_row; j++)
      {
        colvec[i]=matrix_elements[j][i]
      }
    }
  }
};
*/




#endif